package com.ponhu.ea2.goodsCenter.provider.schedule;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.ponhu.ea2.entity.PhSeries;
import com.ponhu.ea2.goodsCenter.provider.mapper.LuxSkuInfoMapper;
import com.ponhu.ea2.goodsCenter.provider.mapper.PhSeriesMapper;
import com.ponhu.ea2.goodsCenter.provider.mapper.PonHuGoodsTradePriceInfoMapper;
import com.ponhu.ea2.goodsCenter.provider.service.LuxPriceService;
import com.ponhu.ea2.goodsCenter.provider.service.LuxSkuInfoService;
import com.ponhu.ea2.goodsCenter.provider.task.LuxPriceByRunnableTask;
import com.ponhu.ea2.goodsCenter.provider.task.LuxSkuInfoTask;
import com.ponhu.ea2.vo.PonHuGoodsTradePriceInfoVo;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;

/**
 * @author luyu
 * @create 2021-09-22 18:01
 */
@Slf4j
@Component
public class LuxPriceTask {

    @Resource
    LuxSkuInfoMapper luxSkuInfoMapper;

    @Resource
    PonHuGoodsTradePriceInfoMapper ponHuGoodsTradePriceInfoMapper;

    @Resource
    PhSeriesMapper phSeriesMapper;

    @Resource
    LuxPriceService luxPriceService;

    @Resource
    LuxSkuInfoService luxSkuInfoService;

    private String brands = "225,226,227,228,229,230,231,232,233,234";// 国内十大平台的id

    private int pageSize = 1000;// 每页显示的数量

    private final Integer LIST_LIMIT = 200;// List分割条数

    @XxlJob("luxPriceTask")
    public void luxPriceTask(){
        String param = XxlJobHelper.getJobParam();
        if(StringUtils.isBlank(param)){
            // 如果没有传递参数,则取昨天的日期
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Calendar c = Calendar.getInstance();
            c.add(Calendar.DAY_OF_MONTH, -1);
            Date m1 = c.getTime();
            param = format.format(m1);
        }
        // 处理胖总管查询的门店商品,去掉重复的系列
        List<String> seriesList = checkSericeId();
        // 调用方法,保存价格数据
        saveLuxPrice(param,seriesList);
    }

    /**
     * 查询胖总管中三里屯门店商品的系列信息,并处理重复的系列
     * @return
     */
    public List<String> checkSericeId(){

        List<PonHuGoodsTradePriceInfoVo> ponHuGoodsTradePriceInfoVos =
                ponHuGoodsTradePriceInfoMapper.queryPonhuGoodspriceInfo();
        Map<String, String> hashMap = new HashMap<>();
        for (int i = 0; i < ponHuGoodsTradePriceInfoVos.size(); i++) {
            // 根据胖总管的系列名称查询商品中心的系列表,获取系列id
            List<PhSeries> series = phSeriesMapper.selectList(
                    new QueryWrapper<PhSeries>().eq("name",
                            ponHuGoodsTradePriceInfoVos.get(i).getSeries()).orderByDesc("level"));
            // 如果存在,则根据id查询,不存在则跳过
            if(!CollectionUtils.isEmpty(series)){
                // 判断是否已经存在key
                String s = hashMap.get(ponHuGoodsTradePriceInfoVos.get(i).getSeries());
                if(StringUtils.isNotBlank(s)){
                    break;
                }else {
                    hashMap.put(ponHuGoodsTradePriceInfoVos.get(i).getSeries(),series.get(0).getId().toString());
                }
            }
        }
        return new ArrayList<String>(hashMap.values());
    }

    /**
     * 保存同行价
     * @param param 时间
     * @param seriesList 系列List
     */
    public void saveLuxPrice(String param,List<String> seriesList){
        // 自定义线程池,核心线程为5,最大线程为20,队列为500
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(6, 20, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(500), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
        // 开启线程超时自动关闭
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        // 遍历胖总管的系列id集合
        log.info("总共有{}个系列,分别是{}",seriesList.size(),seriesList.toString());
        for (String series : seriesList) {
            int totalPages = 1; // 总页码,初始化默认为1
            for (int page = 1; page <= totalPages; page++) {
                // 正式url
                String url = "http://121.37.250.170:8085/potQueryList?p="
                        +page+"&ps="+pageSize+"&time="+param+"_"+param+"&s="+series+"&v="+brands;
                Map map = sendGet(url);
                totalPages = (int)Double.parseDouble(map.get("pageNum").toString());// 将返回的总页码赋值
                List list =  (ArrayList)map.get("pages");// 返回的数据
                log.info("系列id为{}的同行价数量为{}条",series,map.get("total").toString());
                log.info("时间为{},系列id为{}的同行价第{}页的数量为{}条",param,series,page,list.size());
                try {
                    // 按指定条数进行数据分割处理
                    List<List> parts = Lists.partition(list, LIST_LIMIT);
                    parts.stream().forEach(iter -> {
                        threadPoolExecutor.execute(new LuxPriceByRunnableTask(luxPriceService,iter,param,luxSkuInfoMapper));
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


    @XxlJob("luxSkuInfoTask")
    public void luxSkuInfoTask(String param){
        int totalPages = 1; // 总页码,初始化默认为1
        final String time = LocalDateTime.now().format(
                DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss"));
        //CountDownLatch countDownLatch = new CountDownLatch(20);
        // 自定义线程池,核心线程为5,最大线程为20,队列为500
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(6, 20, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(500), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
        // 开启线程超时自动关闭
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        for (int page = 1; page <= totalPages; page++) {// 循环页码,查询出每一页的数据
        //for (int page = 1; page <= 1; page++) {
            String url = "http://121.37.250.170:8085/goods?p="+page+"&ps="+pageSize+"&v="+brands;
            Map map = sendGet(url);
            if(totalPages == 1){
                totalPages = (int)Double.parseDouble(map.get("totalPages").toString());// 将返回的总页码赋值
            }
            List list =  (ArrayList)map.get("content");// 返回的数据
            try {
                // 按指定条数进行数据分割处理
                List<List> parts = Lists.partition(list, LIST_LIMIT);
                parts.stream().forEach(iter -> {
                    threadPoolExecutor.execute(new LuxSkuInfoTask(luxSkuInfoService,luxSkuInfoMapper,iter,time));
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        log.info("执行完毕时间为{}",LocalDateTime.now().format(
                DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss")));
    }

    public static Map sendGet(String url) {
        String result = "";
        BufferedReader in = null;
        Gson gson = new Gson();
        Map map = new HashMap();
        try {
            String urlNameString = url;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            map = gson.fromJson(result, map.getClass());
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }finally {
            // 使用finally块来关闭输入流
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return map;
    }
}
